# Tiny server based on BusyBox and Go

Create a new directory to keep everything organized. I have used port `8081` to keep things different from inside container and out. But you can use any port as you wish.

This should create a simple HTTP server for static files around ~10mb in size. BusyBox should take ~1.2mb (smaller than Alpine Linux) and go server around 7.9mb. Compared to a latest nginx image being 126MB when I'm writing this. This would be an overkill for a static server, hence this Go based one.


## With Docker Compose

To me, with Docker Compose, it becomes a lot more cleaner and manageable. If you want to do this with Dockerfile, see below.

`nano docker-compose.yml`
```
web:
  image: busybox
  volumes:
   - ./server:/bin/server
   - ./www:/www
  ports:
   - "8080:8081"
  command: /bin/server
```

`nano server.go`
```
package main

import (
	"log"
	"net/http"
)

func main() {
	http.Handle("/", http.FileServer(http.Dir("./www")))
	log.Fatal(http.ListenAndServe(":8081", nil))
}
```

This can be run with: `go run server.go` for testing, then tried `http://localhost:8081` on browsers.


Can be built with: `GOOS=linux GOARCH=386 go build ./server.go`

This will create a `server` file.

Ensure that there is a `www` directory: `mkdir www`

Put an `index.html` file as a test: `echo "Your server is working!!" > www/index.html`


Now run: `docker-compose up` \
Open `http://localhost:8080` \
Ctrl+C to stop server


## With Dockerfile

You can also try this with Dockerfile.

Build the `server` executable like normal: `GOOS=linux GOARCH=386 go build ./server.go`

`nano Dockerfile`
```
FROM busybox
COPY ./server /bin/
COPY ./www /www
CMD /bin/server
```

Build the image with:
`docker build -t go-server .`

Verify it's created:
`docker images | grep "go-server"`

Run it:
`docker run -p 8080:8081 --rm -it go-server`

Now access your server from `http://localhost:8080`

## Enabling HTTPS

_Note: This section has not been successfully tested. HTTPS works with `go run`, but not with `docker-compose`._

Create `server.key` and `server.crt`:

```
$ openssl genrsa -out server.key 2048
$ openssl ecparam -genkey -name secp384r1 -out server.key
$ openssl req -new -x509 -sha256 -key server.key -out server.crt
```

For "Common Name" question, I enter `localhost`. Blank input for others is fine.

Now in `server.go` replace the line:
```
log.Fatal(http.ListenAndServe(":8081", nil))
```
with:
```
log.Fatal(http.ListenAndServeTLS(":8081", "server.crt", "server.key", nil))
```

Rebuild your go script:
`GOOS=linux GOARCH=386 go build ./server.go`

Add under `volumes` in `docker-compose.yml`:
```
  volumes:
   ...
   - ./server.crt:/server.crt
   - ./server.key:/server.key
```

We're putting the server.crt and server.key files in `/` so that our Go program finds it without problems.

To run:
`docker-compose up`

Now visit: `https://localhost:8080`. It should show a `Warning: Potential Security Risk Ahead` or other SSL error depending on your browser. Simply [add the ssl cert](https://gist.github.com/cecilemuller/9492b848eb8fe46d462abeb26656c4f8#trust-the-local-ca) in your trusted list and enjoy!


**Ref:**
- https://tutorialedge.net/golang/creating-simple-web-server-with-golang/
- https://www.sohamkamani.com/blog/2016/11/22/docker-server-busybox-golang/
